/*******************************************************************************
 * Copyright (c) 2006 CEA List.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     CEA List - initial API and implementation
 *******************************************************************************/
package com.cea.papyrus.diagram.classdiagram.editpart;

import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.PositionConstants;
import org.eclipse.draw2d.XYLayout;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.palette.PaletteDrawer;
import org.eclipse.uml2.uml.Class;
import org.eclipse.uml2.uml.Dependency;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.ElementImport;
import org.eclipse.uml2.uml.NamedElement;
import org.eclipse.uml2.uml.Package;
import org.eclipse.uml2.uml.TemplateSignature;

import com.cea.papyrus.core.PapyrusMessages;
import com.cea.papyrus.core.PapyrusPlugin;
import com.cea.papyrus.core.directedit.IDirectEdition;
import com.cea.papyrus.core.editor.ModelManager;
import com.cea.papyrus.core.editor.mouseoveraction.ActionHandleManager;
import com.cea.papyrus.core.editpart.ContainerHighlightEditPolicy;
import com.cea.papyrus.core.editpart.ContainerWithSemanticEditPart;
import com.cea.papyrus.core.figures.IconFigure;
import com.cea.papyrus.core.helper.ModelerHelper;
import com.cea.papyrus.core.ui.dialogs.PapyrusMessageDialog;
import com.cea.papyrus.core.utils.Debug;
import com.cea.papyrus.diagram.classdiagram.figures.PackageFigure;
import com.cea.papyrus.diagraminterchange2.di2.GraphNode;
import com.cea.papyrus.diagraminterchange2.di2.Uml1SemanticModelBridge;

/**
 * Controller class for {@link Package}.
 */
public class PackageEditPart extends ContainerWithSemanticEditPart {

	/**
	 * Creates a new PackageEditPart.
	 * @param modelManager manager in charge of models, graphic and domain
	 * @param graphNode parent of the graph node controlled by this edit part
	 */
	public PackageEditPart(GraphNode graphNode,ModelManager modelManager) {
		super(graphNode,modelManager);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected void createEditPolicies(){
		super.createEditPolicies();
		// edit policies are installed only if presentation is not shape
		if(ModelerHelper.IMAGE_STEREOTYPE_PRESENTATION != getPresentation()) {
			installEditPolicy(EditPolicy.SELECTION_FEEDBACK_ROLE, new ContainerHighlightEditPolicy());//Does not run?!!
			installEditPolicy(EditPolicy.LAYOUT_ROLE, new ClassLayoutEditPolicy((XYLayout) getContentPane().getLayoutManager()));
		}
		// Install mouse hover
		installActionHandle();
		// Add shortcuts on package figure for creating a new owned package
	}

	/**
	 * Install Action handles for this editPart.
	 * Use same toolEntries than in palette
	 */
	protected void installActionHandle() {
		// Install mouse hover
		ActionHandleManager actionMngr = new ActionHandleManager(this);	
		// Create a toolbar of actions.
		try{
			PaletteDrawer entries = new PaletteDrawer("creation tool");
			entries.add(PapyrusPlugin.creationToolFactory.getCombinedTemplateCreationToolEntry(
					PapyrusMessages.AddPackageCommand_Label, 
					PapyrusMessages.AddPackageCommand_Description, 
					Package.class, 
					null));

			// Add shortcuts on package figure for creating a class a package
			entries.add(PapyrusPlugin.creationToolFactory.getCombinedTemplateCreationToolEntry(
					PapyrusMessages.AddClassCommand_Label, 
					PapyrusMessages.AddClassCommand_Description,
					Class.class,
					null));

			entries.add(PapyrusPlugin.creationToolFactory.getCombinedTemplateCreationToolEntry(
					PapyrusMessages.AddTemplateSignatureCommand_Label,
					PapyrusMessages.AddTemplateSignatureCommand_Description,
					TemplateSignature.class,
					null));

			// Add shortcuts on package figure for creating a dependency with a package
			entries.add(PapyrusPlugin.creationToolFactory.getConnectionCreationToolEntry(
					PapyrusMessages.AddDependencyCommand_Label,
					PapyrusMessages.AddDependencyCommand_Description,
					Dependency.class,
					null));
			actionMngr.addTool(entries, PositionConstants.EAST, false, 5);
		} catch (Exception e) {
			PapyrusMessageDialog.display(e.getMessage(), e);
		}
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected IFigure createFigure() {
		// Force initialization of the manager when figure has changed
		manager = null;	
		directEditionMode = IDirectEdition.UNDEFINED_DIRECT_EDITOR;
		// Try to get figure from ContainerWithSemanticEditPart
		IFigure fig = super.createFigure();
		if (fig != null) {
			return fig;
		}
		// else
		return new PackageFigure();		
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public Package getUmlElement(){
		Element e=((Uml1SemanticModelBridge)getGraphNode().getSemanticModel()).getElement();
		// case of element import
		if(e instanceof ElementImport){
			return (org.eclipse.uml2.uml.Package)((ElementImport) e).getImportedElement();
		}
		// this is a simple Package
		return (org.eclipse.uml2.uml.Package)e;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected void refreshVisuals() {
		Debug.debug(this, "refreshvisuals", channel);

		Dimension size = getGraphNode().getSize();
		Point p = getGraphNode().getPosition();
		Rectangle r = new Rectangle(p ,size);

		IFigure fig = getFigure();
		fig.setBounds(r);

		// if fig is a stereotype figure
		if (!(fig instanceof PackageFigure)) {
			IconFigure icf= (IconFigure) getFigure();
			icf.setName(((NamedElement) getUmlElement()).getName());

		} else {
			org.eclipse.uml2.uml.Package currentPackage = getUmlElement();
			com.cea.papyrus.umlutils.Element currentElement = new com.cea.papyrus.umlutils.Element(getUmlElement());

			// Retrieve current class and figure
			PackageFigure f = (PackageFigure) fig; //get Class figure

			// if fig is a PackageFigure
			f.refreshColors(getGraphNode());
			f.refreshPresentation(getPresentation(), currentPackage, getGraphNode());
			boolean hasIcon  = currentElement.hasIcon();
			boolean hasShape = currentElement.hasShape();
			f.refreshStereotypes(f.getHeaderFigure().stereotypesLabel(this), getPresentation(), hasIcon, hasShape);

			f.setName(currentPackage.getName());// set the name of the class

			//qualifiedName
			GraphNode gp= (GraphNode) getGraphNode().getContainer();
			f.refreshQualifiedName(gp, getGraphNode(), getUmlElement());
		}
		((GraphicalEditPart) getParent()).setLayoutConstraint(this, fig, r);
	}

	/**
	 * Returns the Figure of this as a PackageFigure.
	 * @return PackageFigure of this.
	 * @deprecated
	 * @see #getFigure()
	 */
	protected PackageFigure getPackageFigure() {
		return (PackageFigure) getFigure();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public IFigure getContentPane() {
		if (getFigure() instanceof PackageFigure) {
			return ((PackageFigure)getFigure()).getContentPane();
		} else {
			// Figure is a shape
			return getFigure();
		}
	}

	/**
	 * Returns the Name Label of this edit part.
	 * @return Label the label figure from the graphical representation
	 */
	protected Label getNameLabel() {
		IFigure fig = getFigure();
		if (fig instanceof IconFigure) {
			return (Label) fig;
		} else if (fig instanceof PackageFigure) {
			return ((PackageFigure) fig).getNameLabel();
		} else {
			Debug.error(this, "PackageEditPart::getTextFigure() : Unknown Figure type.", channel);
			return null;
		}
	}

//	/**
//	 * Init the label direct edit manager.
//	 * This method should be called when a Direct Edit request is performed.
//	 */
//	protected void initLabelEditManager() {
//		if(manager==null) {
//			// locator for the cell editor (on the name label)
//			CellEditorLocator locator = new SimpleCellEditorLocator(getNameLabel());
//
//			// defining how properties are modified in the model
//			PropertyAccessor accessor = new PropertyAccessor() {
//				public String getPropertyName() {
//					return "Name";
//				}
//				public String getValue() {
//					return ((org.eclipse.uml2.uml.NamedElement) getUmlElement()).getName();
//				}
//				public void setValue(String value) {
//					((org.eclipse.uml2.uml.NamedElement) getUmlElement()).setName(value);  
//				}
//			};
//			// defines the controler: link between model and view
//			ILabelControler labelControler = new LabelControler(getNameLabel(), accessor);
//
//			// creates the editing manager.
//			manager = new LabelDirectEditManager(this, locator, labelControler);
//		}
//	}
//
//
//	/**
//	 * the direct edit mechanism requires the edit part to handle the direct edit
//	 * request.
//	 * 
//	 * @param req the request that called the direct edit.
//	 */
//	public void performDirectEdit(Request req) {
//		initLabelEditManager();
//		manager.show();
//	}
//
//	/* (non-Javadoc)
//	 * @see org.eclipse.gef.editparts.AbstractEditPart#performRequest(org.eclipse.gef.Request)
//	 */
//	/**
//	 * 
//	 * 
//	 * @param request 
//	 */
//	@Override
//	public void performRequest(Request request){
//		if (RequestConstants.REQ_DIRECT_EDIT.equals(request.getType())) {
//			performDirectEdit(request);
//		}
//	}
}
